home *** CD-ROM | disk | FTP | other *** search
- require 5.000;
-
- # PerlVision - A class library to do ANSI graphics and textmode GUI
- # By Ashish Gulhati (hash@well.sf.ca.us)
- # V.0.1.0
- #
- # (C) Ashish Gulhati, 1995. All Rights Reserved.
- #
- # Free electronic distribution permitted. You are free to use
- # PerlVision in your own code so long as this copyright message stays
- # intact. PerlVision or derived code may not be used in any commercial
- # product without my prior written or PGP-signed consent. Please e-mail
- # me if you make significant changes, or just want to let me know what
- # you're using PerlVision for.
-
- package pv;
-
- sub initvision {
- my $mode = shift;
- system "stty", '-icanon', '-echo', '-ignbrk', '-isig', '-brkint';
- $|=1;
- ($mode) && (print ("\e[0;11m"));
- ($mode) || (print ("\e[0;10m"));
- $TL=(".","\xDA")[$mode];
- $TR=(".","\xBF")[$mode];
- $HZ=("-","\xC4")[$mode];
- $VT=("|","\xB3")[$mode];
- $BL=("`","\xC0")[$mode];
- $BR=("'","\xD9")[$mode];
- $LB=(" ","\xDD")[$mode];
- $RB=(" ","\xDE")[$mode];
- $TICK=("X","\xFB")[$mode];
- $MARK=("*","\x04")[$mode];
- $VS = &screen;
- $RS = &screen;
- }
-
- sub exitvision {
- system "stty sane";
- print ("\e[0;10m");
- print ("\e[?25h");
- print ("\e[40;37m");
- print ("\e[2J");
- print ("\e[1;1H");
- }
-
- sub screen {
- my ($i, @qq, @xx);
- for ($i=1; $i<25; $i++) {
- $qq[$i] = &line;
- }
- for ($i=1; $i<25; $i++) {
- $xx[$i] = " " x 81;
- }
- $i = [1,1,0,\@qq,\@xx];
- }
-
- sub line {
- my ($i, @qq);
- my $param=shift;
- for ($i=1; $i<81; $i++) {
- $qq[$i] = 0;
- }
- $i = \@qq;
- }
-
- sub pvprint { # Puts stuff to virtual screen
- my $input = shift;
- $input=~s/\n.*//;
- my $qq=length($input);
- my $i;
- ($qq+$VS[1] >80) && ($qq=80-$VS[1]);
- for ($i=0; $i<$qq; $i++) {
- $VS[3][$VS[0]][$VS[1]+$i]=$VS[2];
- }
- substr($VS[4][$VS[0]],$VS[1],$qq)=substr($input,0,$qq);
- $VS[1]+=$qq;
- }
-
- sub refresh { # Compares virtual screen with real screen
- my ($i,$j,$fore,$hi,$back); # and does a differential update
- my (@rline,@vline,$linebuf,$ypos);
- print ("\e[?25l");
- my $COLOR=$VS[2];
- $back = $VS[2] % 10;
- $fore = ($VS[2]-$back) / 10;
- $hi = ($fore > 7 ? 1 : 0);
- $fore = ($fore > 7 ? $fore-8 : $fore);
- print "\e[0;$hi;3$fore;4$back"."m";
- for ($i=1;$i<25;$i++) {
- unless (($RS[4][$i] eq $VS[4][$i]) &&
- (join("",@{${$RS[3]}[$i]}) eq join("",@{${$VS[3]}[$i]}))) {
- @rline=split("",$RS[4][$i]);
- @vline=split("",$VS[4][$i]);
- $linebuf="\e[$i;1H";
- my $ypos=1;
- for ($j=1;$j<81;$j++) {
- if ($RS[3][$i][$j]!=$VS[3][$i][$j]) {
- ($ypos!=$j) && ($linebuf.="\e[$i;$j"."H");
- if ($VS[3][$i][$j]!=$COLOR) {
- $back = $VS[3][$i][$j] % 10;
- $fore = ($VS[3][$i][$j]-$back) / 10;
- $hi = ($fore > 7 ? 1 : 0);
- $fore = ($fore > 7 ? $fore-8 : $fore);
- $linebuf.="\e[0;$hi;3$fore;4$back"."m";
- $COLOR = $VS[3][$i][$j];
- }
- $RS[3][$i][$j]=$VS[3][$i][$j];
- $linebuf.=$vline[$j];
- $ypos=$j+1;
- }
- elsif ($rline[$j] ne $vline[$j]) {
- ($ypos!=$j) && ($linebuf.="\e[$i;$j"."H");
- if ($RS[3][$i][$j]!=$COLOR) {
- $back = $RS[3][$i][$j] % 10;
- $fore = ($RS[3][$i][$j]-$back) / 10;
- $hi = ($fore > 7 ? 1 : 0);
- $fore = ($fore > 7 ? $fore-8 : $fore);
- $linebuf.="\e[0;$hi;3$fore;4$back"."m";
- $COLOR = $RS[3][$i][$j];
- }
- $linebuf.=$vline[$j];
- $ypos=$j+1;
- }
- }
- $RS[4][$i]=$VS[4][$i];
- print $linebuf;
- }
- }
- $back = $VS[2] % 10;
- $fore = ($VS[2]-$back) / 10;
- $hi = ($fore > 7 ? 1 : 0);
- $fore = ($fore > 7 ? $fore-8 : $fore);
- print "\e[0;$hi;3$fore;4$back"."m";
- }
-
- sub redraw {
-
- # Will put it in sometime
-
- }
-
- sub pv_tellregion {
- my ($x1, $y1, $x2, $y2) = @_;
- my ($i, $j, $region);
- my @yy=(); my @qq=(); my @xx=();
- for ($i=$y1; $i<=$y2; $i++) {
- for ($j=$x1; $j<=$x2; $j++) {
- $qq[$i-$y1][$j-$x1]=$RS[3][$i][$j];
- }
- $xx[$i-$y1] = substr($RS[4][$i], $x1, $x2-$x1);
- }
- $region = [\@qq,\@xx];
- return ($region);
- }
-
- sub pv_putregion {
- my ($x1, $y1, $x2, $y2, $region) = @_;
- my ($i, $j);
- for ($i=$y1; $i<=$y2; $i++) {
- for ($j=$x1; $j<=$x2; $j++) {
- $VS[3][$i][$j] = ${$region->[0]->[$i-$y1]}[$j-$x1];
- }
- substr($VS[4][$i], $x1, $x2-$x1) = $region->[1]->[$i-$y1];
- }
- }
-
- sub refresh_cursor {
- print ("\e[$VS[0];$VS[1]"); print ("H");
- print ("\e[?25h");
- }
-
- sub set_cur_pos {
- $VS[1]=shift;
- $VS[0]=shift;
- }
-
- sub cursor_up {
- ($VS[0]>1) && ($VS[0]--);
- }
-
- sub cursor_down {
- ($VS[0]<24) && ($VS[0]++);
- }
-
- sub cursor_forward {
- ($VS[1]<81) && ($VS[1]++);
- }
-
- sub cursor_back {
- ($VS[1]>1) && ($VS[1]--);
- }
-
- sub bgcolor {
- if (($_[0] < 8) && ($_[0] >= 0)) {
- $VS[2]=$VS[2]-$VS[2]%10+$_[0];
- }
- }
-
- sub fgcolor {
- if (($_[0] < 16) && ($_[0] >= 0)) {
- $VS[2]=$VS[2]%10+($_[0]*10);
- }
- }
-
- sub cls {
- my ($i,$j) = (1,1);
- for ($i=1;$i<25;$i++) {
- for ($j=1;$j<81;$j++) {
- $VS[3][$i][$j]=$VS[2];
- $RS[3][$i][$j]=$VS[2];
- }
- $VS[4][$i]=(" " x 81);
- $RS[4][$i]=(" " x 81);
- }
- my $back = $VS[2] % 10;
- my $fore = ($VS[2]-$back) / 10;
- my $hi = ($fore > 7 ? 1 : 0);
- $fore = ($fore > 7 ? $fore-8 : $fore);
- print "\e[0;$hi;3$fore;4$back"."m";
- print ("\e[2J");
- refresh();
- }
-
- sub cleol {
- my ($y,$x) = @VS[0..1];
- substr($VS[4][$y],$x,80-$x)= (" " x (80-$x));
- substr($RS[4][$y],$x,80-$x)= (" " x (80-$x));
- for ($x;$x<81;$x++) {
- $VS[3][$y][$x]=$VS[2];
- $RS[3][$y][$x]=$VS[2];
- }
- my $back = $VS[2] % 10;
- my $fore = ($VS[2]-$back) / 10;
- my $hi = ($fore > 7 ? 1 : 0);
- $fore = ($fore > 7 ? $fore-8 : $fore);
- print ("\e[$VS[0];$VS[1]"); print ("H");
- print "\e[0;$hi;3$fore;4$back"."m";
- print ("\e[K");
- refresh();
- }
-
- sub box { # Draws your basic 3D box.
- my ($x1,$y1,$x2,$y2,$style,$bgcolor)=@_;
- my $lines=$x2-$x1;
- my $j;
- my ($TOPL,$BOTR);
- if ($style) {$TOPL=15; $BOTR=0}
- else {$TOPL=0; $BOTR=15}
- set_cur_pos($x1,$y1);
- bgcolor ($bgcolor);
- fgcolor ($TOPL);
- pvprint ($TL); pvprint ($HZ x ($lines-1));
- fgcolor ($BOTR); pvprint ($TR);
- for ($j=$y1+1; $j<$y2; $j++) {
- set_cur_pos($x1,$j);
- fgcolor ($TOPL); pvprint ($VT);
- pvprint (" " x ($lines-1));
- fgcolor ($BOTR); pvprint ($VT);
- }
- set_cur_pos($x1,$y2);
- fgcolor ($TOPL); pvprint ($BL);
- fgcolor ($BOTR); pvprint ($HZ x ($lines-1));
- pvprint ($BR);
- }
-
- sub standard { # Makes a standard screen (optimized)
- bgcolor (6); cls; bgcolor(7);
- set_cur_pos (1,1); cleol;
- set_cur_pos (1,2); cleol;
- set_cur_pos (1,3); cleol;
- box (2,1,79,3,1,7);
- box (2,4,79,24,0,6);
- }
-
- sub getkey { # Gets a keystroke and returns a code
- my $key = getc; # and the key if it's printable.
- my $keycode = 0;
- if ($key eq "\e") {
- $key = getc;
- if ($key eq "[") { # Prolly a keypad key
- $key = getc;
- if ($key =~ /[A-D1-6]/) {
- ($key eq "1") && (getc eq "~") && ($keycode = 1);
- ($key eq "2") && (getc eq "~") && ($keycode = 2);
- ($key eq "3") && (getc eq "~") && ($keycode = 3);
- ($key eq "4") && (getc eq "~") && ($keycode = 4);
- ($key eq "5") && (getc eq "~") && ($keycode = 5);
- ($key eq "6") && (getc eq "~") && ($keycode = 6);
- ($key eq "A") && ($keycode = 7);
- ($key eq "B") && ($keycode = 8);
- ($key eq "C") && ($keycode = 9);
- ($key eq "D") && ($keycode = 10);
- }
- }
- elsif ($key =~ /[WwBbFfIiQqVv<>DdXxHh]/) { # Meta keys
- ($key =~ /[Qq]/) && ($keycode = 11); # M-q
- ($key eq ""
- || $key eq "") && ($keycode = 12); # M-<del>
- ($key =~ /[Bb]/) && ($keycode = 13); # M-b
- ($key =~ /[Dd]/) && ($keycode = 14); # M-d
- ($key =~ /[Vv]/) && ($keycode = 15); # M-v
- ($key eq "<") && ($keycode = 16); # M-<
- ($key eq ">") && ($keycode = 17); # M->
- ($key =~ /[Hh]/) && ($keycode = 18); # M-h
- ($key =~ /[Xx]/) && ($keycode = 19); # M-x
- ($key =~ /[Ff]/) && ($keycode = 20); # M-f
- ($key =~ /[Ii]/) && ($keycode = 21); # M-i
- ($key =~ /[Ww]/) && ($keycode = 22); # M-w
- }
- else {
- $keycode = 100;
- }
- }
- elsif ($key =~ /[A-Za-z0-9_ \t\n\r~\`!@#\$%^&*()\-+=\\|{}[\];:'"<>,.\/?]/) {
- ($keycode = 200);
- }
- return ($key, $keycode);
- }
-
- "Perlvision. (C) Ashish Gulhati, 1995";
-